package group_01.MultiSnakeServer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Observer;

/**GameHandler is the "game"class. Every game has its own GameHandler that receives data and forwards it to all the joined players.
 * 
 * @author Martin Nume
 *
 */
public class GameHandler implements Runnable, Observer{
	//name of game
	private String gameName;
	//gameID, unique for every game.
	private String gameID;
	private Thread thread;
	//Max number of players in this game
	private int maxPlayers;
	//Joined players
	private ArrayList<PlayerHandler> playerList;
	private LinkedList<String> buffer;
	private boolean runGame;
	
	
	
	public GameHandler(String gameName, int maxPlayers) {
		this.maxPlayers = maxPlayers;
		this.gameName = gameName;
		playerList = new ArrayList<PlayerHandler>();
		buffer = new LinkedList<String>();
		thread=new Thread(this);
		runGame = false;
		
		thread.start();
	}

	public void setGameID(String id) {
		gameID=id;
	}
	public String getGameID() {
		return gameID;
	}
	
	public String getGameName() {
		return gameName;
	}
	public int getMaxPlayers() {
		return maxPlayers;
	}
	public int getCurrentPlayers() {
		return playerList.size();
	}
	
	/**
	 * Adds a player to this game
	 * @param playerHandler
	 */
	public synchronized void addPlayer(PlayerHandler playerHandler) {
		//add an observer to this playerobject. so this game knows when the playerhandler has recevied data
		playerHandler.addObserver(this);
		//start the playerthread
		playerHandler.start();
		//add the playerhandler to the list of joined players
		playerList.add(playerHandler);
		//set the unique id to the playerHandler
		playerHandler.setPlayerID(gameID + "." + playerList.size());//need to set Id after adding the PlayerHandler to the playerList
		
		//if we have reached the maximum number of players, we start the game
		if(playerList.size() == maxPlayers){
			//send the command to all players that the game is starting
			sendPlayerIDs();
			runGame=true;
			
		}
	}
	
	public synchronized void removePlayer(String id){
		
	}
	
	public synchronized void pushToBuffer(String str) {
		buffer.add(str);
	}
	
	/**
	 * Sends the unique id and startcommand to every player in this game
	 */
	private void sendPlayerIDs(){
		for(int i =0; i < playerList.size(); i++){
				playerList.get(i).pushToBuffer( "start;" + i + ";" + maxPlayers);
		}
		
	}
	

	@Override
	public void run() {
		while(!Thread.interrupted()) {
			System.out.print("");
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			while(buffer.size() > 0 && runGame) {
				//poll the first datastring in the buffer....
				String txt = buffer.poll();
				for(PlayerHandler player : playerList)
				{
					// and send it to all the clients.
						player.pushToBuffer(txt);
						
				}				
			}
		}
	}

	/**
	 * This method is called When Playerhandlers notifys that they have received data from the clients 
	 */
	@Override
	public void update(Observable observClass, Object input) {
		if(observClass instanceof PlayerHandler && input instanceof String) {
			//add it to the buffer
			pushToBuffer((String)input);
			//for debugging purposes
			System.out.println("ADDING TO BUFFER" + (String)input);
		}
		
	}
}
